package com.libre.qr;


import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.Hashtable;

import javax.imageio.ImageIO;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.Sides;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class PrintBarCode {

    // 传入文件和打印机名称
    public static void JPGPrint(String filePath,String printerName) throws PrintException {
        File file = new File(filePath);
        if (file == null) {
            System.err.println("缺少打印文件");
        }
        InputStream fis = null;
        try {
            // 设置打印格式，如果未确定类型，可选择autosense
            // DocFlavor flavor = DocFlavor.INPUT_STREAM.JPEG;
            DocFlavor flavor = DocFlavor.INPUT_STREAM.PNG;
            // 设置打印参数
            PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
            aset.add(new Copies(1)); //份数
            //aset.add(MediaSize.ISO.A4); //纸张
            // aset.add(Finishings.STAPLE);//装订
            //aset.add(Sides.DUPLEX);//单双面
            aset.add(Sides.ONE_SIDED);//单面
            //打印区域,左边距，上边距，打印宽度，打印高度，单位毫米
            aset.add(new MediaPrintableArea(1, 1, 10, 10, MediaPrintableArea.MM));
            // 定位打印服务
            PrintService printService = null;
            if (printerName != null) {
                //获得本台电脑连接的所有打印机
                PrintService[] printServices = PrinterJob.lookupPrintServices();
                if(printServices == null || printServices.length == 0) {
                    System.out.print("打印失败，未找到可用打印机，请检查。");
                    return ;
                }
                //匹配指定打印机
                for (int i = 0;i < printServices.length; i++) {
                    System.out.println(printServices[i].getName());
                    if (printServices[i].getName().contains(printerName)) {
                        printService = printServices[i];
                        break;
                    }
                }
                if(printService==null){
                    System.out.print("打印失败，未找到名称为" + printerName + "的打印机，请检查。");
                    return ;
                }
            }
            fis = new FileInputStream(file); // 构造待打印的文件流
            Doc doc = new SimpleDoc(fis, flavor, null);
            DocPrintJob job = printService.createPrintJob(); // 创建打印作业
            job.print(doc, aset);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        } finally {
            // 关闭打印的文件流
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 根据内容生成二维码数据
     * @param content 二维码文字内容[为了信息安全性，一般都要先进行数据加密]
     * @param width 二维码照片宽度
     * @param height 二维码照片高度
     * @return
     * @throws IOException
     */
    public static void createQRCode(String content, int width, int height, String filePath) throws IOException{
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        //设置字符编码
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        // 指定纠错等级
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        BitMatrix matrix = null;
        try {
            matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
            Path path = FileSystems.getDefault().getPath(filePath);
            MatrixToImageWriter.writeToPath(matrix, "PNG", path);
        } catch (WriterException e) {
            e.printStackTrace();
        }
    }

    /**
     * 合并两张图片
     * @param a
     * @param b
     * @return
     * @throws IOException
     */
    private static BufferedImage mergerImage(String pathA,String pathB) throws IOException {
        BufferedImage a =ImageIO.read(new File(pathA));
        BufferedImage b =ImageIO.read(new File(pathB));
        int width=a.getWidth();
        int height=a.getHeight()+b.getHeight();
        BufferedImage bufferedImage=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics=bufferedImage.createGraphics();
        graphics.drawImage(a, 0,0, a.getWidth(), a.getHeight(),null);
        graphics.drawImage(b, 0,a.getHeight(), b.getWidth(), b.getHeight(),null);
        graphics.dispose();

        File outputfile = new File(QR_CODE_IMAGE_PATH);
        ImageIO.write(bufferedImage, "PNG", outputfile);
        return bufferedImage;
    }

    /**
     * 根据str,font的样式以及输出文件目录
     * @param str	字符串
     * @param font	字体
     * @param outFile	输出文件位置
     * @param width	宽度
     * @param height	高度
     * @throws Exception
     */
    public static void createImage(String str, Font font, File outFile,
                                   Integer width, Integer height) throws Exception {
        // 创建图片
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_BGR);
        Graphics g = image.getGraphics();
        g.setClip(0, 0, width, height);
        g.setColor(Color.WHITE);
        // 先用黑色填充整张图片,也就是背景
        g.fillRect(0, 0, width, height);
        // 在换成红色
        g.setColor(Color.BLACK);
        // 设置画笔字体
        g.setFont(font);
        /** 用于获得垂直居中y */
        Rectangle clip = g.getClipBounds();
        FontMetrics fm = g.getFontMetrics(font);
        int ascent = fm.getAscent();
        int descent = fm.getDescent();
        int y = (clip.height - (ascent + descent)) / 2 + ascent;
        // 256 340 0 680
        g.drawString(str, 10, y); //字符串，开始位置，结束位置
        /*
        for (int i = 0; i < 6; i++) {
            // 画出字符串
            g.drawString(str, i * 680, y);
        }
        */
        g.dispose();
        // 输出png图片
        ImageIO.write(image, "png", outFile);
    }

    public static void createImage_pro(String str, Font font, String pathA) throws Exception {
        // 创建图片
        BufferedImage image = ImageIO.read(new File(pathA));
        Graphics g = image.getGraphics();
        g.setColor(Color.BLACK);
        // 设置画笔字体
        g.setFont(font);
        g.drawString(str, 5, 145); //字符串，开始位置，结束位置
        g.dispose();
        File outFile = new File(pathA);
        // 输出png图片
        ImageIO.write(image, "png", outFile);
    }

    private static final String QR_CODE_IMAGE_PATH = System.getProperty("user.dir") + "\\src\\main\\resources\\qr\\";
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        /**/
        try {
            String bacode="08000033%ABS 727%181125WG-211181130%55%170";
            createQRCode(bacode, 10, 10, QR_CODE_IMAGE_PATH);
            System.out.println("输出条码图片成功....!" );
            //createImage_pro(bacode, new Font("宋体", Font.PLAIN, 12),QR_CODE_IMAGE_PATH);
            //System.out.println("输出添加文字图片成功....!" );
            String printerName = "HP LaserJet Professional M1213nf MFP";//打印机名包含字串
            JPGPrint(QR_CODE_IMAGE_PATH,printerName);
        } catch (IOException e) {
            System.out.println("Could not generate QR Code, IOException :: " + e.getMessage());
        }

        //合并图片
        //createImage("A1003", new Font("宋体", Font.PLAIN, 20), new File("e:/a.png"), 150, 32);
        //mergerImage(QR_CODE_IMAGE_PATH,"e:/a.png");
		/*
		String bacode="08000033%ABS 727%181125WG-211181130%55%170";
		createQRCode(bacode, 150, 150, QR_CODE_IMAGE_PATH);
		createImage_pro(bacode, new Font("宋体", Font.PLAIN, 12),QR_CODE_IMAGE_PATH);
		*/

    }
}
